package com.springboot.config;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.sql.DataSource;

import org.assertj.core.util.Arrays;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.concurrent.ListenableFutureCallbackRegistry;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.alibaba.druid.pool.DruidDataSource;
import com.springboot.component.LoginInterceptor;
import com.springboot.component.MyErrorAttributes;
import com.springboot.component.MyLocaleResolver;
import com.springboot.servlet.MyFilter;
import com.springboot.servlet.MyListener;
import com.springboot.servlet.MyServlet;

/**
 * If you want to take complete control of Spring MVC, you can add your
 * own @Configuration annotated with @EnableWebMvc.
 */

// @EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

	/**
	 * 制定url和视图映射
	 */
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/").setViewName("login");
		registry.addViewController("/index.html").setViewName("login");
		registry.addViewController("/main.html").setViewName("dashboard");
		WebMvcConfigurer.super.addViewControllers(registry);
	}

	/**
	 * If you wish to provide custom instances of RequestMappingHandlerMapping,
	 * RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you
	 * can declare a WebMvcRegistrations(this is a interface,the offical
	 * document privided is WebMvcRegistrationsAdapter which has something
	 * wrong) instance to provide such components.
	 */
	@Bean
	public WebMvcRegistrations getWebMvcRegistrationsAdapter() {
		return new WebMvcRegistrations() {

		};
	}

	/**
	 * 
	 * 添加一个LocaleResolver
	 */
	@Bean
	public LocaleResolver getLocaleResolver() {
		return new MyLocaleResolver();
	}

	/**
	 * 添加登录拦截器，排除静态资源的路径，登录相关的路径
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/", "/index.html",
				"/login.html", "/webjars/**", "/static/**");
		WebMvcConfigurer.super.addInterceptors(registry);
	}

	/**
	 * 指定静态文件
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
	}

	/**
	 * 使用阿里巴巴德鲁伊数据库连接池，使用自定义的bean，否则，在yml中配置的druid连接池的配置无效
	 */
	@Bean
	@ConfigurationProperties("spring.datasource")
	public DataSource getDruidDataSource() {
		return new DruidDataSource();
	}

	/**
	 * 添加一个自定义的错误属性bean
	 */
	@Bean
	public MyErrorAttributes getDefaultErrorAttributes() {
		return new MyErrorAttributes();
	}

	// @Bean
	// 除了在application.properties中配置内嵌tomcat（或者其他servlet容器）的参数属性，还可以用这种方式配置内嵌的servlet容器的参数属性设置
	public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> getWebServerFactoryCustomizer() {
		return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() {
			@Override
			public void customize(ConfigurableServletWebServerFactory factory) {
				factory.setPort(9000);
			}
		};
	}

	// 往容器中注册servlet
	@Bean
	public ServletRegistrationBean<MyServlet> getServlet() {
		// 使用了泛型,url-mapping的配置必须带上/
		return new ServletRegistrationBean<MyServlet>(new MyServlet(), "/myservlet");
	}

	// 往容器中注册listener
	@Bean
	public FilterRegistrationBean<MyFilter> getFilter() {
		FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<MyFilter>();
		bean.setFilter(new MyFilter());
		Collection<String> collection = new ArrayList<String>();
		collection.add("/*");
		bean.setUrlPatterns(collection);
		return bean;
	}

	// 往容器中注册listener
	@Bean
	public ServletListenerRegistrationBean<MyListener> getListener() {
		ServletListenerRegistrationBean<MyListener> bean = new ServletListenerRegistrationBean<MyListener>();
		bean.setListener(new MyListener());
		return bean;
	}

}